package com.atXiao.food.util;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.atXiao.food.config.Log;
import com.atXiao.food.constant.BusSignConstant;
import com.atXiao.food.constant.BuscodeConstant;
import com.atXiao.food.service.impl.OssServiceImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

@Component
public class OSSUtil {

    public final static Log logger = new Log(OSSUtil.class);

    // OSS Endpoint 外网访问域名，以北京为例。
    @Value("${ali.endpoint}")
    private String ENDPOINT;
    // AccessKeyId 和 AccessKeySecret 是先前创建用户生成的。
    @Value("${ali.accessKeyId}")
    private String ACCESS_KEY_ID;
    @Value("${ali.accessKeySecret}")
    private String ACCESS_KEY_SECRET;
    // Bucket 名称
    @Value("${ali.bucketName}")
    private String BUCKET_NAME;

    /**
     * 上传本地文件到 OSS 并返回公共访问 URL。
     *
     * @param objectName 对象名称，包括路径和文件名。
     * @param file       本地文件。
     * @return 文件的公共访问 URL。
     */
    public String uploadFileToOSS(String objectName, File file) {
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

        // 指定 Bucket 中的对象键（路径和文件名）。
        PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, objectName, file);

        // 上传文件到 OSS。
        ossClient.putObject(putObjectRequest);

        // 设置文件为公共读。
        ossClient.setBucketAcl(BUCKET_NAME, CannedAccessControlList.PublicRead);

        // 生成公共访问 URL。
        URL url = ossClient.generatePresignedUrl(BUCKET_NAME, objectName, new Date(System.currentTimeMillis() + 3600 * 1000));

        // 关闭 OSS 客户端。
        ossClient.shutdown();

        return url.toString();
    }

    /**
     * 上传 InputStream 到 OSS 并返回公共访问 URL。
     *
     * @param objectName  对象名称，包括路径和文件名。
     * @param inputStream 输入流。
     * @return 文件的公共访问 URL。
     */
    public String uploadInputStreamToOSS(String objectName, InputStream inputStream) {
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        // 指定 Bucket 中的对象键（路径和文件名）。
        PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, objectName, inputStream);
        // 上传 InputStream 到 OSS。
        PutObjectResult result = ossClient.putObject(putObjectRequest);
        logger.info("", BusSignConstant.TASTE_FOOD, BuscodeConstant.FILE_UPLOAD, "上传结果:" + JSONObject.toJSONString(result));
        // 设置文件为公共读。
        ossClient.setBucketAcl(BUCKET_NAME, CannedAccessControlList.PublicRead);
        // 生成公共访问 URL。
        URL url = ossClient.generatePresignedUrl(BUCKET_NAME, objectName, new Date(System.currentTimeMillis() + 3600 * 1000));
        // 关闭 OSS 客户端。
        ossClient.shutdown();
        return url.toString();
    }
}
